﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Media.Effects;

namespace LanderWpf
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        #region Fields and properties

        public static MainWindow Current;

        public Lander Lander { get; set; }
        public Agent Agent { get; set; }

        public Image LanderMapPic { get; set; }

        public int MapTileSize
        {
            get { return (int) MapCanvas.Width / Lander.Surface.GetLength(0); }
        }

        public int MapShipPadding
        {
            get { return 2; }
        }

        #endregion

        #region Construction and creation

        public MainWindow()
        {
            InitializeComponent();

            Current = this;

            Lander = new Lander();
            Agent = new Agent(Lander);
            if (InformedRadioButton.IsChecked.HasValue && InformedRadioButton.IsChecked.Value)
                Agent.SearchType = LandingSearch.Informed;
        }

        private void LanderWindow_Loaded(object sender, RoutedEventArgs e)
        {
            Root.DataContext = Lander;

            CreateMapCanvas();
            UpdateHeightCanvas();
            UpdateMapCanvas();

            Agent.Start();
        }

        public void CreateMapCanvas()
        {
            MapCanvas.Children.Clear();
            int height = Lander.Surface.GetLength(0);
            int width = Lander.Surface.GetLength(1);
            for (int i = 0; i < height; i++)
            {
                for (int j = 0; j < width; j++)
                {
                    Rectangle r = new Rectangle();
                    r.Width = MapTileSize;
                    r.Height = MapTileSize;

                    r.Stroke = new SolidColorBrush(Colors.Black);

                    if (Lander.Surface[i, j] == SurfaceType.Rock)
                        r.Fill = new ImageBrush(Resources["RockImg"] as BitmapImage);
                    else
                        r.Fill = new ImageBrush(Resources["SmoothImg"] as BitmapImage);

                    MapCanvas.Children.Add(r);

                    Canvas.SetTop(r, i * MapTileSize);
                    Canvas.SetLeft(r, j * MapTileSize);
                }
            }

            LanderMapPic = new Image();
            LanderMapPic.Source = new BitmapImage(new Uri("lm.png", UriKind.Relative));
            LanderMapPic.Width = MapTileSize - MapShipPadding * 2;
            
            var ef = new DropShadowEffect();
            ef.Direction = 0;
            ef.BlurRadius = 17;
            ef.ShadowDepth = 0;
            LanderMapPic.Effect = ef;

            MapCanvas.Children.Add(LanderMapPic);
        }

        #endregion

        #region Updating view

        public void UpdateHeightCanvas()
        {
            double height = 200 - Lander.Altitude * 10;
            LanderHeightPic.SetValue(Canvas.TopProperty, height);
        }

        public void UpdateMapCanvas()
        {
            double top, left;
            top = MapShipPadding + (MapTileSize * Lander.Lattitude);
            left = MapShipPadding + (MapTileSize * Lander.Longitude);

            LanderMapPic.SetValue(Canvas.TopProperty, top);
            LanderMapPic.SetValue(Canvas.LeftProperty, left);
        }

        public void UpdateCrashed()
        {
            if (Lander.Status == FlightStatus.Crashed)
            {
                ImageSource img = new BitmapImage(new Uri("explosion.png", UriKind.Relative));
                LanderMapPic.Source = img;
                LanderHeightPic.Source = img;

                LanderHeightPic.SetValue(Canvas.TopProperty, 200.0);
            }
        }

        #endregion

        #region Button events

        private void PitchUp_Click(object sender, RoutedEventArgs e)
        {
            Lander.PitchFore();
            UpdateCrashed();
        }

        private void PitchDown_Click(object sender, RoutedEventArgs e)
        {
            Lander.PitchAft();
            UpdateCrashed();
        }

        private void RollLeft_Click(object sender, RoutedEventArgs e)
        {
            Lander.RollLeft();
            UpdateCrashed();
        }

        private void RollRight_Click(object sender, RoutedEventArgs e)
        {
            Lander.RollRight();
            UpdateCrashed();
        }

        private void Ascend_Click(object sender, RoutedEventArgs e)
        {
            Lander.Ascend();
            UpdateHeightCanvas();
            UpdateCrashed();
        }

        private void Descend_Click(object sender, RoutedEventArgs e)
        {
            Lander.Descend();
            UpdateHeightCanvas();
            UpdateCrashed();
        }

        private void SurgeFore_Click(object sender, RoutedEventArgs e)
        {
            Lander.SurgeFore();
            UpdateMapCanvas();
            UpdateCrashed();
        }

        private void SurgeAft_Click(object sender, RoutedEventArgs e)
        {
            Lander.SurgeAft();
            UpdateMapCanvas();
            UpdateCrashed();
        }

        private void SwayLeft_Click(object sender, RoutedEventArgs e)
        {
            Lander.SwayLeft();
            UpdateMapCanvas();
            UpdateCrashed();
        }

        private void SwayRight_Click(object sender, RoutedEventArgs e)
        {
            Lander.SwayRight();
            UpdateMapCanvas();
            UpdateCrashed();
        }

        private void Restart_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            Lander = new Lander();
            Agent = new Agent(Lander);
            if (InformedRadioButton.IsChecked.HasValue && InformedRadioButton.IsChecked.Value)
                Agent.SearchType = LandingSearch.Informed;

            Root.DataContext = Lander;

            ImageSource img = new BitmapImage(new Uri("lm.png", UriKind.Relative));
            LanderMapPic.Source = img;
            LanderHeightPic.Source = img;

            CreateMapCanvas();
            UpdateHeightCanvas();
            UpdateMapCanvas();

            Agent.Start();
        }

        private void StopAutopilotButton_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            Agent.Stop();
        }

        private void StartAutopilotButton_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            Agent.Start();
        }

        private void BruteForceRadioButton_Checked(object sender, RoutedEventArgs e)
        {
            if (Agent != null)
                Agent.SearchType = LandingSearch.Informed;
        }

        private void InformedRadioButton_Checked(object sender, RoutedEventArgs e)
        {
            if (Agent != null)
                Agent.SearchType = LandingSearch.BruteForce;
        }

        #endregion
    }
}
